Device drivers in L4/ARM

If L4 is ported to the ARM then device drivers present an interesting problem. On the ARM, there are only two types of interrupt, normal and fast. It is necessary to interrogate the I/O controller to determine which device caused the interrupt. This is not a problem as such, it is reasonable for the kernel to de-multiplex the interrupt and expose an interface to the drivers that masks this, but the real problem is that all the expansion card interrupts are multiplexed onto one of the I/O controllers lines. When that interrupt is triggered, each expansion card must be interrogated in turn to see if it caused the interrupt. There is a standard way for expansion cards to tell the kernel how to find out if their interrupt has been triggered, but not all cards support this method. For details, see [#!prm!#, page 4-126]

This is soluble in Mach — since the device drivers are in-kernel, interrupts can be passed around the built-in drivers until one claims it. However in L4, this is somewhat more difficult. Since the device drivers are outside the kernel, it is not possible for the kernel to tell a priori which expansion card has caused the interrupt. Unfortunately, L4 allows only one thread to be the recipient of any given interrupt.

In my opinion, L4 should be modified to allow an interrupt to be shared — ie the interrupt should be delivered to all of the threads which have requested it. It is then necessary to have a further protocol which permits the thread to tell the kernel whether or not it has dealt with the interrupt or wishes it to be passed on to other claimants.

However, there is a security problem with this. A thread needs no particular right to associate with an interrupt. Since it is already determined that security shall lie outside the kernel, it makes no sense to make an exception to this rule for device drivers. Any solution ought to be formulated in terms of clans and chiefs. Unfortunately, the kernel is an exception to the clans mechanism. Messages that are sent directly to the kernel bypass all chiefs. I consider this to be a flaw in the implementation of L4.

Another potential solution to this problem is for L4 to treat subsequent claimants of the interrupt specially, and pass them to the first claimant for checking, as if it were the chief for this particular thread. However, this idea is also flawed since the protection it provides can be circumvented by the following sequence:

  1. A second (malicious) thread claims the vector and is approved.
  2. The first thread is killed in order to be replaced by an improved version. The second thread then becomes the primary thread.
  3. The second thread may now deny service to the replacement for the first thread.

The only viable solution to this problem in terms of the current operation of L4 is to have a task external to the kernel which device drivers register themselves with.